﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using Emgu.Util;

namespace CVsift
{
    public partial class Form3 : Form
    {
        public Form3()
        {
            InitializeComponent();
        }

        private void Form3_Load(object sender, EventArgs e)
        {
            string result = MatchHist();
            MessageBox.Show(result); 
        }

        //成对几何直方图匹配 
        private static string MatchHist()
        {
            string haarXmlPath = "D:\\OpenCV\\libemgucv-windows-universal-2.4.10.1940\\opencv\\data\\haarcascades\\haarcascade_frontalface_default.xml";
            HaarCascade haar = new HaarCascade(haarXmlPath);
            int[] hist_size = new int[1] { 256 };//建一个数组来存放直方图数据
            //IntPtr img1 = CvInvoke.cvLoadImage("", Emgu.CV.CvEnum.LOAD_IMAGE_TYPE.CV_LOAD_IMAGE_ANYCOLOR); //根据路径导入图像

            //准备轮廓 
            Image<Bgr, Byte> image1 = new Image<Bgr, byte>("D:\\test\\2.jpg");
            Image<Bgr, Byte> image2 = new Image<Bgr, byte>("D:\\test\\3.jpg");
            MCvAvgComp[] faces = haar.Detect(image1.Convert<Gray, byte>(), 1.4, 1, Emgu.CV.CvEnum.HAAR_DETECTION_TYPE.DO_CANNY_PRUNING, new Size(20, 20), Size.Empty);
            MCvAvgComp[] faces2 = haar.Detect(image2.Convert<Gray, byte>(), 1.4, 1, Emgu.CV.CvEnum.HAAR_DETECTION_TYPE.DO_CANNY_PRUNING, new Size(20, 20), Size.Empty);

            int l1 = faces.Length;
            int l2 = faces2.Length;
            image1 = image1.Copy(faces[0].rect);
            image2 = image2.Copy(faces2[0].rect);
            Image<Gray, Byte> imageGray1 = image1.Convert<Gray, Byte>();
            Image<Gray, Byte> imageGray2 = image2.Convert<Gray, Byte>();
            Image<Gray, Byte> imageThreshold1 = imageGray1.ThresholdBinaryInv(new Gray(128d), new Gray(255d));
            Image<Gray, Byte> imageThreshold2 = imageGray2.ThresholdBinaryInv(new Gray(128d), new Gray(255d));
            //Contour<Point> contour1 = imageThreshold1.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_EXTERNAL);
            Contour<Point> contour1 = imageThreshold1.FindContours();
            Contour<Point> contour2 = imageThreshold2.FindContours();
            IntPtr HistImg1 = CvInvoke.cvCreateHist(1, hist_size, Emgu.CV.CvEnum.HIST_TYPE.CV_HIST_ARRAY, null, 1); //创建一个空的直方图
            IntPtr HistImg2 = CvInvoke.cvCreateHist(1, hist_size, Emgu.CV.CvEnum.HIST_TYPE.CV_HIST_ARRAY, null, 1);

            //CvInvoke.cvHaarDetectObjects();

            IntPtr[] inPtr1 = new IntPtr[1] { imageThreshold1 };
            IntPtr[] inPtr2 = new IntPtr[1] { imageThreshold2 };
            CvInvoke.cvCalcHist(inPtr1, HistImg1, false, IntPtr.Zero); //计算inPtr1指向图像的数据，并传入HistImg1中
            CvInvoke.cvCalcHist(inPtr2, HistImg2, false, IntPtr.Zero);
            Stopwatch sw = new Stopwatch();
            sw.Start();
            double compareResult;
            Emgu.CV.CvEnum.HISTOGRAM_COMP_METHOD compareMethod = Emgu.CV.CvEnum.HISTOGRAM_COMP_METHOD.CV_COMP_BHATTACHARYYA;
            CvInvoke.cvNormalizeHist(HistImg1, 1d); //直方图对比方式
            CvInvoke.cvNormalizeHist(HistImg2, 1d);
            compareResult = CvInvoke.cvCompareHist(HistImg1, HistImg2, compareMethod);
            //compareResult = CvInvoke.cvMatchShapes(HistImg1, HistImg2, Emgu.CV.CvEnum.CONTOURS_MATCH_TYPE.CV_CONTOURS_MATCH_I3, 1d);
            sw.Stop();
            double time = sw.Elapsed.TotalMilliseconds;
            return string.Format("成对几何直方图匹配（匹配方式：{0}），结果：{1:F05}，用时：{2:F05}毫秒\r\n", compareMethod.ToString("G"), compareResult, time);
        }
    }
}
